package pers.vic.practice;

import java.util.List;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.stream.Collectors;

/**
 * 描述:模拟虚拟存储器中用于页面置换的 FIFO 算法

 * @author Vic.xu
 * @date 2022-04-01 16:28
 */
public class FifoPageReplacementStrategy extends AbstractPageReplacement {

    @Override
    public void replace(int n, int[] pagesSequence) {

        printPagesSequence("FIFO", n, pagesSequence);
        Queue<Integer> queue = new ArrayBlockingQueue<>(n);
        int missNumber = 0;
        for (int seq : pagesSequence) {
            System.out.print("访问页号:" + seq + " 访问前：" + getQueueDesc(queue, n));
            StringBuilder sb = new StringBuilder();
            if (queue.contains(seq)) {
                sb.append("\t不缺页");
            }else {
                missNumber++;
                sb.append("\t缺页");
                if (queue.size() >= n) {
                    sb.append("\t弹出 " + queue.poll());
                }
                queue.add(seq);
                sb.append("\t置入 " + seq);
            }
            System.out.print(sb.toString());
            System.out.println(" 访问后：" + getQueueDesc(queue, n));

        }
        printPageMissRate(missNumber, pagesSequence.length);
    }

    /**
     * 获得队列的描述
     */
    private static String getQueueDesc(Queue<Integer> queue, int n){
        List<String> list = queue.stream().map(String::valueOf).collect(Collectors.toList());
        int size = list.size();
        while (n - size++ > 0) {
            list.add("-");
        }
        return " | " + String.join(" | ", list) + " | ";
    }

}
